// ReactorEx3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "SOCK_WrapperFacade.h"
#include "AlarmEvent.h"
#include "LogEvent.h"
#include "PatientEvent.h"
#include "RequestPatient.h"
#include "LogAcceptor.h"
#include "Reactor.h"
#include "Acceptor.h"
#include "Connector.h"

//#define _SERVER					1

#define DEFAULT_PORT_LOG		27015
#define DEFAULT_PORT_PATIENT	27016
#define DEFAULT_PORT_ALARM		27017

int _tmain(int argc, _TCHAR* argv[])
{

	unsigned long address = 0x7F000001;

	// Convert server address to hexadecimal base.
	if (argc > 1) {
		printf("Server set as %s\n", argv[1]);
		address = ntohl(inet_addr((const char*)argv[1]));
	} else
		printf("Server set as localhost\n");

	// On windows start socket 2.2 system
	WSADATA wsa_data;
	WORD version_requested = MAKEWORD(2, 2);
	int error = WSAStartup(version_requested, &wsa_data);
	if (error != 0) return -1;

#ifdef _SERVER
	// Test with all event services (Log, Patient and Alarm)
	INET_Addr logAddr(DEFAULT_PORT_LOG, address);
	Acceptor<LogEvent, SOCK_Acceptor> logAcceptor(Reactor::instance(), &logAddr);

	INET_Addr patientAddr(DEFAULT_PORT_PATIENT, address);
	Acceptor<PatientEvent, SOCK_Acceptor> patientAcceptor(Reactor::instance(), &patientAddr);
	
	INET_Addr alarmAddr(DEFAULT_PORT_ALARM, address);
	Acceptor<AlarmEvent, SOCK_Acceptor> alarmAcceptor(Reactor::instance(), &alarmAddr);
	
	// Receiving connections and events (Alarm, Log and Patient)
	while (1) {
		Reactor::instance()->handleEvents();
	}

#else
	bool asyncConnect = true; // Or false - then blocking connect is used

	// Client implementation
	// Test with all event services (Log, Patient and Alarm)
	Connector<ServiceHandler, SOCK_Connector> *patientConnector = new Connector<ServiceHandler, SOCK_Connector>(Reactor::instance());
	RequestPatient *reqPatient = new RequestPatient(Reactor::instance());
	INET_Addr *patientAddr = new INET_Addr(DEFAULT_PORT_PATIENT, address);   
	patientConnector->connect(reqPatient, patientAddr, asyncConnect);

	// Simulate generating events (Alarm, Log and Patient)
	while (1) {

		if (asyncConnect == true) {
			Reactor::instance()->handleEvents();
			Sleep(100);
			Reactor::instance()->handleEvents();
			reqPatient->getPatientInfo();
		} else
		{
			reqPatient->getPatientInfo();
			Reactor::instance()->handleEvents();
		}
	}

#endif


/* TESTING first version
	// Creates reactor 
	Reactor *itsReactor = Reactor::instance();

	// Register event handlers
	itsReactor->registerHandler(*(new AlarmEvent(itsReactor, (HANDLE)1)), READ_EVENT);
	itsReactor->registerHandler(*(new LogEvent(itsReactor, (HANDLE)2)), READ_EVENT);
	itsReactor->registerHandler(*(new PatientEvent(itsReactor, (HANDLE)3)), READ_EVENT);
	itsReactor->registerHandler(*(new LogAcceptor(itsReactor, (HANDLE)4)), ACCEPT_EVENT);

	itsReactor->handleEvents();

	Sleep(2000);
*/

	return 0;
}

